Skip to content

Conversation

@Natim
Copy link

@Natim Natim commented Oct 27, 2025

  • I understand that this repository is auto-generated and my pull request may not be merged

Changes being requested

Avoid tweaking Union API to make it works with Python 3.14

Additional context & links

Fixed #2704 to work properly with Python 3.14

@Natim Natim requested a review from a team as a code owner October 27, 2025 17:33
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@Natim Natim mentioned this pull request Oct 28, 2025
@1155159410
Copy link

Thanks for this PR. I think it’s quite urgent since the current OpenAI API isn’t working on Python 3.14 because of this issue.

@RobertCraigie
Copy link
Collaborator

Thanks for the PR but this isn't the correct fix, the places that read the __discriminator__ property need to be updated as well

@Natim
Copy link
Author

Natim commented Nov 4, 2025

The discriminator property need to be updated as well

Would you like for me to do so?
My understanding was that some of the code was generated automatically and PR couldn't be approved directly like that, reason why I didn't put much effort fixing everything related to it.

@Natim
Copy link
Author

Natim commented Nov 5, 2025

🧩 The Root Cause

Starting with Python 3.14, typing.Union (and also types.UnionType for | syntax) is now fully immutable — you can no longer attach arbitrary attributes to them (they have no __dict__).
Hence this line fails with:

cast(CachedDiscriminatorType, union).__discriminator__ = details

With the error:

AttributeError: 'typing.Union' object has no attribute '__discriminator__' and no __dict__ for setting new attributes

This behavior worked in ≤ 3.13 because Union objects allowed dynamic attributes, but that’s gone.

@Natim
Copy link
Author

Natim commented Nov 5, 2025

✅ The Correct Fix

We can’t store metadata on the Union type itself anymore.
Instead, we can keep a sidecar cache (a WeakKeyDictionary) keyed by the union type.

Here’s how you can safely patch both OpenAI and Anthropic implementations:

Step 1 – Create a global cache

Add this near the top of the module (just after CachedDiscriminatorType is defined):

import weakref

# Global cache since typing.Union objects are now immutable (Python 3.14+)
_DISCRIMINATOR_CACHE: "weakref.WeakKeyDictionary[type, DiscriminatorDetails]" = weakref.WeakKeyDictionary()

Step 2 – Update _build_discriminated_union_meta

Replace

if isinstance(union, CachedDiscriminatorType):
    return union.__discriminator__

With

cached = _DISCRIMINATOR_CACHE.get(union)
if cached is not None:
    return cached

Step 3 - Update the ___discriminator__ set

Replace

cast(CachedDiscriminatorType, union).__discriminator__ = details
return details

With

_DISCRIMINATOR_CACHE[union] = details
return details

@Natim
Copy link
Author

Natim commented Nov 5, 2025

🧠 Why This Works

  • WeakKeyDictionary lets cached entries disappear when their type objects are garbage-collected.
  • Works across all supported Python versions.
  • Preserves existing “caching” semantics without mutating Union objects.

@Natim
Copy link
Author

Natim commented Nov 5, 2025

@RobertCraigie I updated my PR implementing the suggested plan. Let me know if this works for you.

@Natim Natim changed the title Update _models.py to handle Python 3.14 Update _models.py to handle Python 3.14 Nov 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AttributeError typing.Union object has no attribute __discriminator__ and not __dict__ for setting new attributes

3 participants